const HouseModel = require("../model/HouseModel");
// 引入日志服务、日志类型
const logService = require("../utils/logService.js");
const LOG_TYPES = require("../constants/logTypes.js");

// 根据仓库类型来确定 Code 前缀(用于区域编号生成)
const STORAGE_TYPE_PREFIX_MAP = {
  1: "CA", // 常温 (Constant Ambient)
  2: "RA", // 冷藏 (Refrigerated Ambient)
  3: "FA", // 冷冻 (Frozen Ambient)
  4: "OA", // 其他 (Other Ambient)
};

// 名称校验正则表达式 (中文/英文/数字/括号/空格/井号/短横线, 2-100个字符)
const HOUSE_NAME_REGEX = /^[\u4e00-\u9fa5a-zA-Z0-9\s()（）#\-]{2,100}$/;

class HouseController {
  constructor() {
    this.houseModel = new HouseModel();
  }
  // 校验仓库数据并设置默认值
  _validateHouseData = (data, isUpdate = false) => {
    const errors = {};
    const requiredFields = ["name", "type", "condition", "contact_phone"];

    for (const field of requiredFields) {
      if (!isUpdate || data[field] !== undefined) {
        if (!data[field] || String(data[field]).trim() === "") {
          errors[field] = `${field} 不能为空`;
          continue;
        }
      }
    }

    if (data.name && !HOUSE_NAME_REGEX.test(data.name)) {
      errors.name = "仓库名称格式不正确";
    }

    if (data.type !== undefined) {
      const typeInt = parseInt(data.type);
      if (isNaN(typeInt) || ![1, 2, 3, 4].includes(typeInt)) {
        errors.type = "仓库类型无效";
      } else {
        data.type = typeInt;
      }
    }

    if (data.user_id !== undefined && data.user_id !== null) {
      const userId = parseInt(data.user_id);
      if (isNaN(userId) || userId <= 0) {
        errors.user_id = "负责人ID必须是有效的正整数";
      } else {
        data.user_id = userId;
      }
    } else if (!isUpdate && data.user_id === undefined) {
      data.user_id = null;
    } else if (data.user_id === null) {
      data.user_id = null;
    }

    if (data.status !== undefined) {
      data.status = parseInt(data.status);
      if (![0, 1].includes(data.status)) {
        errors.status = "状态值无效，必须为 1 (启用) 或 0 (停用)";
      }
    } else if (!isUpdate) {
      data.status = 1;
    }

    if (data.code !== undefined || data.house_id !== undefined) {
      errors.system_field = "仓库编号和ID应由系统管理，不允许手动修改";
    }

    return errors;
  };
  _validateHouseAreaData = (data, isUpdate = false) => {
    const errors = {};
    const requiredFields = ["area_name", "storage_type"];

    for (const field of requiredFields) {
      if (!isUpdate || data[field] !== undefined) {
        if (
          data[field] === undefined ||
          data[field] === null ||
          String(data[field]).trim() === ""
        ) {
          errors[field] = `${field} 不能为空`;
        }
      }
    }

    if (data.area_name && !HOUSE_NAME_REGEX.test(data.area_name)) {
      errors.area_name = "区域名称格式不正确";
    }

    if (data.storage_type !== undefined) {
      const typeInt = parseInt(data.storage_type);
      if (isNaN(typeInt) || !STORAGE_TYPE_PREFIX_MAP[typeInt]) {
        errors.storage_type = "存储类型无效";
      } else {
        data.storage_type = typeInt;
      }
    }

    if (data.condition !== undefined && String(data.condition).trim() !== "") {
      if (String(data.condition).length > 100) {
        errors.condition = "存储条件不能超过 100 个字符";
      }
    } else if (data.condition === undefined && !isUpdate) {
      data.condition = "";
    } else if (data.condition !== undefined) {
      data.condition = String(data.condition).trim();
    }

    if (data.status !== undefined) {
      data.status = parseInt(data.status);
      const allowedAreaStatuses = [0, 1, 2, -1];
      if (isNaN(data.status) || !allowedAreaStatuses.includes(data.status)) {
        errors.status = `状态值无效，必须为 ${allowedAreaStatuses.join(
          " / "
        )} 之一`;
      }
    } else if (!isUpdate) {
      data.status = 1;
    }

    if (data.code !== undefined || data.area_id !== undefined) {
      errors.system_field = "区域编号和ID应由系统管理，不允许手动提供或修改";
    }

    if (data.house_id !== undefined) {
      if (isUpdate) {
        errors.house_id = "区域的所属仓库不允许修改";
      } else {
        data.house_id = parseInt(data.house_id);
      }
    }
    return errors;
  };
  // 新增仓库 (POST /house)
  createHouse = async (req, res) => {
    const data = req.body;

    const validationErrors = this._validateHouseData(data, false);
    if (Object.keys(validationErrors).length > 0) {
      return res
        .status(400)
        .json({ code: 1, msg: Object.values(validationErrors)[0] });
    }

    try {
      const isDuplicate = await this.houseModel.isHouseCodeOrNameExist(
        "name",
        data.name
      );
      if (isDuplicate) {
        return res
          .status(400)
          .json({ code: 1, msg: `仓库名称 [${data.name}] 已存在。` });
      }
    } catch (err) {
      console.error(err.message);
      return res.status(500).json({ code: 1, msg: "唯一性检查失败。" });
    }
    // 插入，获取ID，生成Code，回写Code
    try {
      const { houseId, finalCode } =
        await this.houseModel.addHouseWithCodeTransaction(data);

      const op_type_num = LOG_TYPES.ADD_WAREHOUSE;
      const locationInfo =
        data.address && String(data.address).trim() !== ""
          ? data.address
          : "未填写地址";
      const op_desc = logService.formatLog(op_type_num, {
        name: data.name,
        code: finalCode,
        house_id: houseId,
        location: locationInfo,
      });
      logService.addLog(req, {
        op_type: op_type_num,
        op_desc,
      });
      return res.status(201).json({
        code: 0,
        msg: "新增仓库成功",
        data: { house_id: houseId, code: finalCode },
      });
    } catch (err) {
      console.error(err.message);
      return res.status(500).json({ code: 1, msg: "新增仓库失败。" });
    }
  };
  // 更新仓库 (PUT /house/:id)
  updateHouse = async (req, res) => {
    const houseId = parseInt(req.params.id);
    const data = req.body;

    if (isNaN(houseId) || Object.keys(data).length === 0) {
      return res
        .status(400)
        .json({ code: 1, msg: "ID无效或没有提供更新数据。" });
    }

    const validationErrors = this._validateHouseData(data, true);
    if (Object.keys(validationErrors).length > 0) {
      return res
        .status(400)
        .json({ code: 1, msg: Object.values(validationErrors)[0] });
    }

    let currentHouse;
    try {
      currentHouse = await this.houseModel.getHouseDetail(houseId);
      if (!currentHouse) {
        return res.status(404).json({ code: 1, msg: "仓库不存在。" });
      }
    } catch (err) {
      console.error(err.message);
      return res.status(500).json({ code: 1, msg: "获取仓库信息失败。" });
    }

    if (data.name !== undefined) {
      try {
        const isDuplicate = await this.houseModel.isHouseCodeOrNameExist(
          "name",
          data.name,
          houseId
        );
        if (isDuplicate) {
          return res.status(400).json({
            code: 1,
            msg: `仓库名称 [${data.name}] 已被其他仓库使用。`,
          });
        }
      } catch (err) {
        console.error(err.message);
        return res.status(500).json({ code: 1, msg: "唯一性检查失败。" });
      }
    }

    let logStatusChange = false;
    let logType = null;
    if (data.status !== undefined) {
      const newStatus = data.status;
      const currentStatus = currentHouse.status;

      if (newStatus === 1 && currentStatus !== 1) {
        logStatusChange = true;
        logType = LOG_TYPES.ENABLE_WAREHOUSE;
      } else if (newStatus === 0 && currentStatus !== 0) {
        logStatusChange = true;
        logType = LOG_TYPES.DISABLE_WAREHOUSE;
      }
    }

    try {
      const affectedRows = await this.houseModel.updateHouse(houseId, data);

      if (affectedRows === 0) {
        return res.status(200).json({ code: 0, msg: "数据没有改变。" });
      }

      if (logStatusChange && logType) {
        const op_type_num = logType;
        const locationInfo = currentHouse.address || "未填写地址";
        const op_desc = logService.formatLog(op_type_num, {
          name: currentHouse.name,
          house_id: houseId,
          code: currentHouse.code,
          location: locationInfo,
        });

        logService.addLog(req, {
          op_type: op_type_num,
          op_desc,
        });
      }
      return res.status(200).json({ code: 0, msg: "仓库信息更新成功" });
    } catch (err) {
      console.error(err.message);
      return res.status(500).json({ code: 1, msg: "更新仓库信息失败。" });
    }
  };
  // 获取仓库列表
  getHouseList = async (req, res) => {
    try {
      const filters = {
        page: parseInt(req.query.page) || 1,
        pageSize: parseInt(req.query.pageSize) || 10,
        name: req.query.name,
        type: req.query.type !== undefined ? parseInt(req.query.type) : null,
        status: req.query.status,
        userId: req.query.userId,
      };

      const { list, total } = await this.houseModel.getHouseList(filters);

      return res.status(200).json({
        code: 0,
        msg: "获取仓库列表成功",
        data: {
          list,
          total,
          page: filters.page,
          pageSize: filters.pageSize,
        },
      });
    } catch (err) {
      console.error(err.message);
      return res.status(500).json({ code: 1, msg: "获取仓库列表失败。" });
    }
  };
  // 获取单个仓库详情
  getHouseDetail = async (req, res) => {
    const houseId = parseInt(req.params.id);
    if (isNaN(houseId)) {
      return res.status(400).json({ code: 1, msg: "仓库ID无效。" });
    }

    try {
      const detail = await this.houseModel.getHouseDetail(houseId);

      if (!detail) {
        return res.status(404).json({ code: 1, msg: "仓库不存在。" });
      }
      // 获取该仓库下的区域数量
      const { total: area_count } = await this.houseModel.getAreasByHouseId(
        houseId,
        {}
      );
      detail.area_count = area_count;

      return res
        .status(200)
        .json({ code: 0, msg: "获取仓库详情成功", data: detail });
    } catch (err) {
      console.error(err.message);
      return res.status(500).json({ code: 1, msg: "获取仓库详情失败。" });
    }
  };
  // 软删除仓库 (status = 0)
  deactivateHouse = async (req, res) => {
    const houseId = parseInt(req.params.id);
    if (isNaN(houseId)) {
      return res.status(400).json({ code: 1, msg: "仓库ID无效。" });
    }

    const currentHouse = await this.houseModel.getHouseDetail(houseId);
    if (!currentHouse) {
      return res.status(404).json({ code: 1, msg: "仓库不存在。" });
    }
    if (currentHouse.status === 0) {
      return res.status(400).json({ code: 1, msg: "仓库已停用。" });
    }

    try {
      const affectedRows = await this.houseModel.deactivateHouse(houseId);

      if (affectedRows === 0) {
        return res
          .status(500)
          .json({ code: 1, msg: "操作失败，请检查仓库状态。" });
      }

      const op_type_num = LOG_TYPES.DISABLE_WAREHOUSE;
      const locationInfo = currentHouse.address || "未填写地址";
      const op_desc = logService.formatLog(op_type_num, {
        house_id: houseId,
        code: currentHouse.code,
        name: currentHouse.name,
        location: locationInfo,
      });
      logService.addLog(req, {
        op_type: op_type_num,
        op_desc,
      });
      return res.status(200).json({ code: 0, msg: "仓库已停用。" });
    } catch (err) {
      console.error(err.message);
      return res.status(500).json({ code: 1, msg: "停用仓库失败。" });
    }
  };
  // 仓库区域 // 新增仓库区域
  createHouseArea = async (req, res) => {
    const houseId = req.params.houseId;
    const data = req.body;

    const parsedHouseId = parseInt(houseId);
    if (isNaN(parsedHouseId) || parsedHouseId <= 0) {
      return res.status(400).json({ code: 1, msg: "所属仓库ID格式错误" });
    }

    data.house_id = parsedHouseId;

    const validationErrors = this._validateHouseAreaData(data, false);
    if (Object.keys(validationErrors).length > 0) {
      return res
        .status(400)
        .json({ code: 1, msg: Object.values(validationErrors)[0] });
    }
    // 获取仓库 Code 并确定区域前缀
    let houseDetail;
    let houseCode;
    const areaPrefix = STORAGE_TYPE_PREFIX_MAP[data.storage_type];

    if (!areaPrefix) {
      return res
        .status(400)
        .json({ code: 1, msg: "存储类型无效，无法生成区域编号前缀" });
    }

    try {
      // 检查仓库是否存在且启用
      houseDetail = await this.houseModel.getHouseDetail(data.house_id);
      if (!houseDetail || houseDetail.status !== 1) {
        return res
          .status(400)
          .json({ code: 1, msg: "所属仓库不存在或未启用。" });
      }
      houseCode = houseDetail.code;
    } catch (err) {
      console.error(err.message);
      return res.status(500).json({ code: 1, msg: "获取仓库信息失败。" });
    }

    try {
      const check = await this.houseModel.isAreaCompositeKeyExist(
        null,
        data.house_id,
        data.area_name
      );

      if (check.nameExist) {
        return res.status(400).json({
          code: 1,
          msg: `该仓库内已存在名为 [${data.area_name}] 的区域。`,
        });
      }
    } catch (err) {
      console.error(err.message);
      return res.status(500).json({ code: 1, msg: "复合唯一性检查失败。" });
    }
    // 插入，获取ID，生成Code (WHxxx-XXyyy)，回写Code
    try {
      const { areaId, finalCode } =
        await this.houseModel.addAreaWithCodeTransaction(
          data,
          houseCode,
          areaPrefix
        );

      return res.status(201).json({
        code: 0,
        msg: "新增仓库区域成功",
        data: { area_id: areaId, code: finalCode },
      });
    } catch (err) {
      console.error("HouseController.createHouseArea error:", err.message);

      if (
        err.message &&
        typeof err.message === "string" &&
        err.message.includes("Duplicate entry")
      ) {
        return res.status(400).json({
          code: 1,
          msg: `该仓库内已存在名为 [${data.area_name}] 的区域。`,
        });
      }

      return res.status(500).json({
        code: 1,
        msg: "新增仓库区域失败。",
      });
    }
  };
  // 获取某个仓库下的仓库区域列表
  getHouseAreas = async (req, res) => {
    const houseId = parseInt(req.params.houseId);
    if (isNaN(houseId)) {
      return res.status(400).json({ code: 1, msg: "仓库ID无效。" });
    }

    const filters = {
      areaName: req.query.areaName,
      status: req.query.status !== undefined ? req.query.status : null,
    };

    try {
      const house = await this.houseModel.getHouseDetail(houseId);
      if (!house) {
        return res.status(404).json({ code: 1, msg: "所属仓库不存在。" });
      }

      const { list, total } = await this.houseModel.getAreasByHouseId(
        houseId,
        filters
      );

      return res.status(200).json({
        code: 0,
        msg: "获取区域列表成功",
        data: {
          house_id: houseId,
          house_name: house.name,
          list,
          total,
        },
      });
    } catch (err) {
      console.error(err.message);
      return res.status(500).json({ code: 1, msg: "获取区域列表失败。" });
    }
  };
  // 获取单个仓库区域详情
  getAreaDetail = async (req, res) => {
    const areaId = parseInt(req.params.id);
    if (isNaN(areaId)) {
      return res.status(400).json({ code: 1, msg: "区域ID无效。" });
    }

    try {
      const detail = await this.houseModel.getAreaDetail(areaId);

      if (!detail) {
        return res.status(404).json({ code: 1, msg: "仓库区域不存在。" });
      }

      return res
        .status(200)
        .json({ code: 0, msg: "获取区域详情成功", data: detail });
    } catch (err) {
      console.error(err.message);
      return res.status(500).json({ code: 1, msg: "获取区域详情失败。" });
    }
  };
  // PUT /house/area/:id (更新区域)
  updateHouseArea = async (req, res) => {
    const areaId = parseInt(req.params.id);
    const data = req.body;

    if (isNaN(areaId) || Object.keys(data).length === 0) {
      return res
        .status(400)
        .json({ code: 1, msg: "ID无效或没有提供更新数据。" });
    }

    const validationErrors = this._validateHouseAreaData(data, true);
    if (Object.keys(validationErrors).length > 0) {
      return res
        .status(400)
        .json({ code: 1, msg: Object.values(validationErrors)[0] });
    }

    // 获取当前区域信息
    let existingArea;
    try {
      existingArea = await this.houseModel.getAreaDetail(areaId);
      if (!existingArea) {
        return res.status(404).json({ code: 1, msg: "待更新的区域不存在。" });
      }
    } catch (err) {
      console.error(err.message);
      return res.status(500).json({ code: 1, msg: "获取区域信息失败。" });
    }

    if (data.area_name !== undefined) {
      try {
        const check = await this.houseModel.isAreaCompositeKeyExist(
          null,
          existingArea.house_id,
          data.area_name,
          areaId
        );

        if (check.nameExist) {
          return res.status(400).json({
            code: 1,
            msg: `仓库 [${existingArea.house_name}] 内已存在同名区域 [${data.area_name}]。`,
          });
        }
      } catch (err) {
        console.error(err.message);
        return res.status(500).json({ code: 1, msg: "唯一性检查失败。" });
      }
    }

    try {
      const affectedRows = await this.houseModel.updateHouseArea(areaId, data);

      if (affectedRows === 0) {
        return res.status(200).json({ code: 0, msg: "数据没有改变。" });
      }

      return res.status(200).json({ code: 0, msg: "仓库区域信息更新成功" });
    } catch (err) {
      console.error(err.message);
      return res.status(500).json({ code: 1, msg: "更新仓库区域信息失败。" });
    }
  };
  // 软删除区域 (status = 0)
  deactivateHouseArea = async (req, res) => {
    const areaId = parseInt(req.params.id);
    if (isNaN(areaId)) {
      return res.status(400).json({ code: 1, msg: "区域ID无效。" });
    }

    // 获取当前区域信息
    const existingArea = await this.houseModel.getAreaDetail(areaId);
    if (!existingArea) {
      return res.status(404).json({ code: 1, msg: "区域不存在。" });
    }
    if (existingArea.status === 0) {
      return res.status(400).json({ code: 1, msg: "区域已处于停用状态。" });
    }

    try {
      const affectedRows = await this.houseModel.deactivateHouseArea(areaId);

      if (affectedRows === 0) {
        return res
          .status(500)
          .json({ code: 1, msg: "操作失败，请检查区域状态。" });
      }

      return res.status(200).json({ code: 0, msg: "仓库区域已停用。" });
    } catch (err) {
      console.error(err.message);
      return res.status(500).json({ code: 1, msg: "停用区域失败。" });
    }
  };
}

module.exports = HouseController;
